﻿<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="WorkflowConfiguration"
    targetNamespace="urn:effun-net-dycox-workflow-conf"
    elementFormDefault="qualified"
    xmlns="urn:effun-net-dycox-workflow-conf"
    xmlns:mstns="urn:effun-net-dycox-workflow-conf"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:m="urn:effun-net-dycox-data-model"
>
  <xs:import namespace="urn:effun-net-dycox-data-model"></xs:import>
  <xs:complexType name="generalStage">
    <xs:all>
      <xs:element name="contract" minOccurs="0" type="stageContract"></xs:element>
      <xs:element name="transition" minOccurs="0" type="transition"></xs:element>
      <xs:element name="hints" minOccurs="0">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="hint" type="hint" maxOccurs="unbounded"></xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="properties" minOccurs="0" type="stageProperties"></xs:element>
    </xs:all>
    <xs:attribute name="name" use="required" type="xs:Name"></xs:attribute>
    <xs:attribute name="displayName" type="xs:string"></xs:attribute>
    <xs:attribute name="type" type="xs:string">
      <xs:annotation>
        <xs:documentation>
          Indicates DWC to use a custom Stage type.
          A valid type should be an instantiable type which derrived from Dycox.Workflows.Stage,
          and has a public constructor with a string parameter that specify the name of its stage.</xs:documentation>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="class" default="Major" type="stageClass"></xs:attribute>
  </xs:complexType>

  <xs:complexType name="stageProperties">
    <xs:sequence>
      <xs:element name="property" maxOccurs="unbounded">
        <xs:complexType>
          <xs:attribute name="name" type="xs:Name" use="required"></xs:attribute>
          <xs:attribute name="value" type="xs:string" use="required"></xs:attribute>
          <xs:attribute name="type" type="m:clrDataTypes"></xs:attribute>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:simpleType name="stageClass">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Major"></xs:enumeration>
      <xs:enumeration value="Minor"></xs:enumeration>
    </xs:restriction>
  </xs:simpleType>

  <xs:complexType name="transition">
    <xs:sequence>
      <xs:element name="enter" minOccurs="0">
        <xs:complexType>
          <xs:all>
            <xs:element name="conditions" minOccurs="0">
              <xs:complexType>
                <xs:complexContent>
                  <xs:extension base="transitConditionSet">
                    <xs:attribute name="errorMessage"></xs:attribute>
                  </xs:extension>
                </xs:complexContent>
              </xs:complexType>
            </xs:element>
            <xs:element name="auto-complete" minOccurs="0" type="autoComplete"></xs:element>
          </xs:all>
        </xs:complexType>
      </xs:element>
      <xs:element name="to" type="mstns:transitTo" minOccurs="0" maxOccurs="unbounded"></xs:element>
      <xs:element name="no-more-step" minOccurs="0">
        <xs:complexType>
          <xs:all>
            <xs:element name="operations" type="operationNMS" minOccurs="0"></xs:element>
          </xs:all>
          <xs:attribute name="rank" type="xs:positiveInteger"></xs:attribute>
        </xs:complexType>
      </xs:element>
      <xs:element name="exit" minOccurs="0">
        <xs:complexType>
          <xs:all>
            <xs:element name="operations" type="operationsExit"></xs:element>
          </xs:all>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="stageContract">
    <xs:all minOccurs="0">
      <xs:element ref="m:model" minOccurs="0"></xs:element>
      <xs:element name="initialization" minOccurs="0">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="property" minOccurs="0" maxOccurs="unbounded">
              <xs:complexType>
                <xs:attribute name="name" type="xs:Name" use="required"></xs:attribute>
                <xs:attribute name="value" ></xs:attribute>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:all>
    <xs:attribute name="type" >
      <xs:simpleType>
        <xs:union memberTypes="xs:string">
          <xs:simpleType>
            <xs:restriction base="xs:Name">
              <xs:enumeration value="default"></xs:enumeration>
            </xs:restriction>
          </xs:simpleType>
        </xs:union>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>

  <xs:complexType name="entranceStage">
    <xs:all>
      <xs:element name="contract" minOccurs="0" type="stageContract"></xs:element>
      <xs:element name="transition" minOccurs="0" type="transition"></xs:element>
      <xs:element name="properties" minOccurs="0" type="stageProperties"></xs:element>
    </xs:all>
    <xs:attribute name="name" use="required" type="xs:Name"></xs:attribute>
    <xs:attribute name="displayName" type="xs:string"></xs:attribute>
    <xs:attribute name="type" type="xs:string"></xs:attribute>
  </xs:complexType>

  <xs:complexType name="hint">
    <xs:all>
      <xs:element name="conditions" type="transitConditionSet" minOccurs="0"></xs:element>
    </xs:all>
    <xs:attribute name="text" type="xs:string"></xs:attribute>
    <xs:attribute name="short" type="xs:string"></xs:attribute>
    <xs:attribute name="kind" default="Information">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="Information"></xs:enumeration>
          <xs:enumeration value="Warning"></xs:enumeration>
          <xs:enumeration value="Error"></xs:enumeration>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>

  <xs:complexType name="injectionStage">
    <xs:all>
      <xs:element name="contract" minOccurs="0" type="stageContract"></xs:element>
      <xs:element name="transition" minOccurs="0" type="transition"></xs:element>
      <xs:element name="properties" minOccurs="0" type="stageProperties"></xs:element>
    </xs:all>
    <xs:attribute name="name" use="required" type="xs:Name"></xs:attribute>
    <xs:attribute name="displayName" type="xs:string"></xs:attribute>
    <xs:attribute name="mode" >
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="Process"></xs:enumeration>
          <xs:enumeration value="Thread"></xs:enumeration>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
    <xs:attribute name="class" default="Major" type="stageClass"></xs:attribute>
    <xs:attribute name="type" type="xs:string"></xs:attribute>
  </xs:complexType>

  <xs:complexType name="transitionOperation">
    <xs:all>
      <xs:element name="conditions" type="mstns:transitConditionSet" minOccurs="0"></xs:element>
    </xs:all>
  </xs:complexType>
  
  <xs:complexType name="threadLockOperation">
    <xs:complexContent>
      <xs:extension base="transitionOperation">
        <xs:attribute name="name" type="xs:Name" use="required"></xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="operationsEnter">
    <xs:all>
    </xs:all>
  </xs:complexType>

  <xs:complexType name="operationsExit">
    <xs:choice maxOccurs="unbounded">
      <xs:element name="custom" minOccurs="0" type="customOperation"></xs:element>
      <xs:element name="start-process" minOccurs="0" type="transitionOperation"></xs:element>
      <xs:element name="abort-process" minOccurs="0" type="abortProcess"></xs:element>
      <xs:element name="suspend-process" minOccurs="0" type="suspendProcess"></xs:element>
      <xs:element name="resume-process" minOccurs="0" type="suspendProcess"></xs:element>
      <xs:choice maxOccurs="unbounded">
          <xs:element name="release-lock" minOccurs="0" type="threadLockOperation"></xs:element>
          <xs:element name="wait-lock" minOccurs="0" type="threadLockOperation"></xs:element>
        </xs:choice>
    </xs:choice>
  </xs:complexType>

  <xs:complexType name="operationNormal">
    <xs:choice>
      <xs:element name="custom" minOccurs="0" type="customOperation"></xs:element>
      <xs:element name="start-process" minOccurs="0" type="transitionOperation"></xs:element>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="release-lock" minOccurs="0" type="threadLockOperation"></xs:element>
        <xs:element name="set-lock" minOccurs="0" type="threadLockOperation"></xs:element>
      </xs:choice>
    </xs:choice>
  </xs:complexType>

  <xs:complexType name="abortProcess">
    <xs:complexContent>
      <xs:extension base="transitionOperation">
        <xs:attribute name="reason" type="xs:string" use="required"></xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="customOperation">
    <xs:complexContent>
      <xs:extension base="transitionOperation">
        <xs:attribute name="type" type="xs:string" use="required"></xs:attribute>
        <xs:attribute name="state" type="xs:string"></xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="suspendProcess">
    <xs:complexContent>
      <xs:extension base="transitionOperation">
        <xs:attribute name="reason">
          <xs:simpleType >
            <xs:restriction base="xs:string">
              <xs:enumeration value="fallback"></xs:enumeration>
              <xs:enumeration value="manual"></xs:enumeration>
            </xs:restriction>
          </xs:simpleType>
        </xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="operationNMS">
    <xs:complexContent>
      <xs:extension base="operationNormal">
        <xs:choice>
          <xs:element name="abort-process" minOccurs="0" type="abortProcess"></xs:element>
          <xs:element name="suspend-process" minOccurs="0" type="suspendProcess"></xs:element>
          <xs:element name="resume-process" minOccurs="0" type="suspendProcess"></xs:element>
        </xs:choice>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="threadLock">
    <xs:attribute name="name" use="required" type="xs:Name"></xs:attribute>
    <xs:attribute name="description" type="xs:string"></xs:attribute>
  </xs:complexType>

  <xs:complexType name="transitTo">
    <xs:all>
      <xs:element name="where" minOccurs="0" maxOccurs="1">
        <xs:complexType>
          <xs:all >
            <xs:element name="conditions" minOccurs="0" maxOccurs="1" type="mstns:transitConditionSet"></xs:element>
            <!--<xs:element name="condition" minOccurs="0">
              <xs:complexType>
                <xs:attribute name="expression" use="required"></xs:attribute>
              </xs:complexType>
            </xs:element>-->
            <xs:element name="user-selected" minOccurs="0" maxOccurs="1">
              <xs:complexType>
                <xs:attribute name="label" type="xs:string"></xs:attribute>
                <xs:attribute name="prompt" type="xs:string"></xs:attribute>
              </xs:complexType>
            </xs:element>
          </xs:all>
        </xs:complexType>
      </xs:element>
      <xs:element name="operations" minOccurs="0" type="operationNormal">
      </xs:element>
    </xs:all>
    <xs:attribute name="stage" type="xs:string"></xs:attribute>
    <xs:attribute name="argument" type="xs:string"></xs:attribute>
    <xs:attribute name="rank" type="xs:positiveInteger"></xs:attribute>
    <xs:attribute name="marshal" type="stepMarshalling"></xs:attribute>
    <xs:attribute name="stepActivation" default="Auto" type="activationMode"></xs:attribute>
  </xs:complexType>

  <xs:simpleType name="stepMarshalling">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Default"></xs:enumeration>
      <xs:enumeration value="NewThreadFromCurrent"></xs:enumeration>
      <xs:enumeration value="NewThreadFromParent"></xs:enumeration>
      <xs:enumeration value="NewThreadFromMain"></xs:enumeration>
    </xs:restriction>
  </xs:simpleType>

  <xs:complexType name="autoComplete">
    <xs:sequence>
      <xs:element name="conditions" type="mstns:transitConditionSet" minOccurs="1" maxOccurs="1"></xs:element>
      <xs:element name="contract" minOccurs="1" maxOccurs="1">
        <xs:complexType>
          <xs:sequence>
            <xs:element minOccurs="1" maxOccurs="unbounded" name="property">
              <xs:complexType>
                <xs:attribute name="name" type="xs:ID" use="required"></xs:attribute>
                <xs:attribute name="value" type="xs:string"></xs:attribute>
                <xs:attribute name="eval" type="xs:string"></xs:attribute>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="stageRelatedType">
    <xs:attribute name="stage" type="xs:string"></xs:attribute>
  </xs:complexType>

  <xs:complexType name="transitConditionSet">
    <xs:choice maxOccurs="unbounded">
      <xs:group ref="mstns:propertyValueConditions" minOccurs="0" maxOccurs="unbounded"></xs:group>
      <xs:element name="conditions" type="mstns:transitConditionSet"></xs:element>
      <xs:element name="custom" type="mstns:customCondition"></xs:element>
    </xs:choice>
    <xs:attribute name="relation" default="And">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="And"></xs:enumeration>
          <xs:enumeration value="Or"></xs:enumeration>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>

  <xs:complexType name="customCondition">
    <xs:attribute name="key" type="xs:string"></xs:attribute>
  </xs:complexType>

  <xs:complexType name="propertyValueCondition" abstract="true">
    <xs:attribute name="property" use="required" type="xs:string"></xs:attribute>
  </xs:complexType>

  <xs:complexType name="compareCondition">
    <xs:complexContent>
      <xs:extension base="mstns:propertyValueCondition">
        <xs:attribute name="valueToCompare" use="required" type="xs:string"></xs:attribute>
        <xs:attribute name="operator" default="Equals">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:enumeration value="Equals"></xs:enumeration>
              <xs:enumeration value="NotEquals"></xs:enumeration>
              <xs:enumeration value="GreaterThan"></xs:enumeration>
              <xs:enumeration value="GreaterThanOrEquals"></xs:enumeration>
              <xs:enumeration value="LessThan"></xs:enumeration>
              <xs:enumeration value="LessThanOrEquals"></xs:enumeration>
              <xs:enumeration value="StringContains"></xs:enumeration>
              <xs:enumeration value="StringStartsWith"></xs:enumeration>
              <xs:enumeration value="StringEndsWith"></xs:enumeration>
              <xs:enumeration value="BitTest"></xs:enumeration>
            </xs:restriction>
          </xs:simpleType>
        </xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="rangeCondition">
    <xs:complexContent>
      <xs:extension base="mstns:propertyValueCondition">
        <xs:attribute name="lowerBound" type="xs:string" use="required"></xs:attribute>
        <xs:attribute name="upperBound" type="xs:string" use="required"></xs:attribute>
        <xs:attribute name="excludeBoundValues" type="xs:boolean"></xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="regexCondition">
    <xs:complexContent>
      <xs:extension base="mstns:propertyValueCondition">
        <xs:attribute name="pattern" type="xs:string" use="required"></xs:attribute>
        <xs:attribute name="ignoreCase" type="xs:boolean"></xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:group name="propertyValueConditions">
    <xs:choice>
      <xs:element name="compare" type="mstns:compareCondition"></xs:element>
      <xs:element name="range" type="mstns:rangeCondition"></xs:element>
      <xs:element name="regex" type="mstns:regexCondition"></xs:element>
    </xs:choice>
  </xs:group>

  <xs:simpleType name="version">
    <xs:restriction base="xs:string">
      <xs:pattern value="\d+\.\d+"></xs:pattern>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="activationMode">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Auto"></xs:enumeration>
      <xs:enumeration value="Manual"></xs:enumeration>
    </xs:restriction>
  </xs:simpleType>

  <xs:element name="workflow">
    <xs:complexType>
      <xs:all>
        <xs:element name="settings">
          <xs:complexType>
            <xs:all>
              <xs:element name="threadLocks" minOccurs="0">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="lock" type="threadLock" minOccurs="0" maxOccurs="unbounded"></xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              <xs:element name="completeConditions" minOccurs="0" type="transitConditionSet">
                
              </xs:element>
            </xs:all>
            <xs:attribute name="displayName" type="xs:string" use="required"></xs:attribute>
            <xs:attribute name="description" type="xs:string"></xs:attribute>
            <xs:attribute name="currentVersion" use="required" type="version"></xs:attribute>
            <xs:attribute name="compatibleVersion" type="version"></xs:attribute>
            <xs:attribute name="processStartMode" type="activationMode"></xs:attribute>
          </xs:complexType>
        </xs:element>
        <xs:element name="stages" minOccurs="0">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="entrance" type="entranceStage"></xs:element>
              <xs:choice maxOccurs="unbounded">
                <xs:element name="stage" type="generalStage" minOccurs="0" maxOccurs="1"></xs:element>
                <xs:element name="injection" type="injectionStage" minOccurs="0" maxOccurs="1"></xs:element>
              </xs:choice>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element ref="m:fileOptions" minOccurs="0"></xs:element>
      </xs:all>
    </xs:complexType>
    <xs:key name="stageNames">
      <xs:selector xpath="mstns:stages/mstns:stage|mstns:stages/mstns:injection"></xs:selector>
      <xs:field xpath="@name"></xs:field>
    </xs:key>
    <xs:keyref name="stageNamesRef" refer="mstns:stageNames">
      <xs:selector xpath=".//mstns:to"></xs:selector>
      <xs:field xpath="@stage"></xs:field>
    </xs:keyref>
    <xs:key name="threadLockNames">
      <xs:selector xpath="mstns:settings/mstns:threadLocks/mstns:lock"></xs:selector>
      <xs:field xpath="@name"></xs:field>
    </xs:key>
    <xs:keyref refer="mstns:threadLockNames" name="keyrefWaitLock">
      <xs:selector xpath=".//mstns:set-lock|.//mstns:wait-lock|.//mstns:release-lock"></xs:selector>
      <xs:field xpath="@name"></xs:field>
    </xs:keyref>
  </xs:element>

</xs:schema>
